package com.uairobot.bill.yz.office.agent.service;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.litong.utils.http.FileUploadUtil;
import com.litong.utils.http.alithttpclient.HUCUtil;
import com.litong.utils.http.alithttpclient.HttpDownloadUtil;
import com.uairobot.bill.yz.office.agent.comp.ResourcesLocationComponent;
import com.uairobot.bill.yz.office.agent.entity.DownloadFile;
import com.uairobot.bill.yz.office.agent.entity.UploadFile;
import com.uairobot.bill.yz.office.agent.entity.YzConvert;
import com.uairobot.bill.yz.office.agent.entity.YzPreview;
import com.uairobot.bill.yz.office.agent.entity.YzTestUpload;
import com.uairobot.bill.yz.office.agent.repository.DownloadFileRepository;
import com.uairobot.bill.yz.office.agent.repository.YzConvertRepository;
import com.uairobot.bill.yz.office.agent.repository.YzPreviewRepository;
import com.uairobot.bill.yz.office.agent.repository.YzTestUploadRepository;

import lombok.extern.slf4j.Slf4j;

/**
 * @author bill robot
 * @date 2020年1月3日_下午3:49:27 
 * @version 1.0 
 * @desc
 */
@Service
@Slf4j
public class YzOfficeService {

  @Value("${yz.office.addr}")
  private String yzOfficeAddr;
  @Autowired
  private BillUploadService bus;
  @Autowired
  private YzTestUploadRepository ytur;
  @Autowired
  private YzConvertRepository ycr;
  @Autowired
  private DownloadFileRepository dfr;
  @Autowired
  private YzPreviewRepository ypr;
  @Autowired
  private FileSaveSerivce fileSaveSerivce;
  @Autowired
  private ResourcesLocationComponent rlc;

  private String projectYzDirName = "data" + File.separator + "yz";
  private String yzDownloadPath = null;

  public YzTestUpload testUpload(MultipartFile file) {
    UploadFile upload = bus.upload(file);
    YzTestUpload findOne = ytur.findOne(upload.getMd5());
    if (findOne == null) {
      String localFilePath = fileSaveSerivce.getLocalFilePath(upload.getUri());
      StringBuilder json = FileUploadUtil.uploadFile(yzOfficeAddr + "/" + "testUpload", localFilePath, "file");
      if (json == null) {
        log.info("上文件发送异常");
        return null;
      }
      findOne = new YzTestUpload();
      findOne.setJson(json.toString());
      findOne.setMd5(upload.getMd5());
      ytur.save(findOne);

    }
    return findOne;
  }

  public String convert(Map<String, String> req) {
    log.info("req : " + req);
    String inputDir = req.get("inputDir");
    Integer convertType = Integer.parseInt(req.get("convertType"));
    YzConvert findOne = ycr.findOne(inputDir);
    String json = null;
    if (findOne == null) {
      json = HUCUtil.post(yzOfficeAddr + "/" + "convert", req);
      findOne = new YzConvert();
      findOne.setInputDir(inputDir);
      findOne.setConvertType(convertType);
      findOne.setJson(json);
      ycr.save(findOne);
    }
    json = findOne.getJson();
    return json;
  }

  public void download(String downloadAddr, OutputStream outputStream, String folderName, String filename, String extension) {
    filename = filename + "." + extension;
    DownloadFile df = dfr.findOne(downloadAddr);
    String downloadPath = getDownloadPath();
    String localPath = null;
    if (df == null) {
      localPath = getLoadPath(downloadPath, folderName, filename);
      String downloadFile = HttpDownloadUtil.downloadFile(localPath, downloadAddr);
      if (downloadFile == null) {
        // 下载出现异常,返回
        return;
      }
      df = new DownloadFile(downloadAddr, filename);
      dfr.save(df);
    } else {
      localPath = getLoadPath(downloadPath, folderName, df.getFilename());
    }
    BufferedOutputStream bufOut = new BufferedOutputStream(outputStream);
    try (BufferedInputStream bufIn = new BufferedInputStream(new FileInputStream(localPath));) {
      FileCopyUtils.copy(bufIn, bufOut);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
  }

  private String getLoadPath(String downloadPath, String folderName, String filename) {
    if (folderName == null) {
      return downloadPath + File.separator + filename;
    } else {
      String folderPath = downloadPath + File.separator + folderName;
      File file = new File(folderPath);
      if (!file.exists()) {
        file.mkdirs();
      }
      return folderPath + File.separator + filename;
    }
  }

  private String getDownloadPath() {
    if (yzDownloadPath == null) {
      yzDownloadPath = rlc.getLocations().get(0) + File.separator + projectYzDirName;
      File file = new File(yzDownloadPath);
      if (!file.exists()) {
        file.mkdirs();
      }
    }
    return yzDownloadPath;
  }

  public YzPreview preview(MultipartFile file) {
    YzTestUpload testUpload = testUpload(file);
    YzPreview yzPreview = ypr.findOne(testUpload.getMd5());
    if (yzPreview == null) {
      JSONObject parseObject = JSON.parseObject(testUpload.getJson());
      Map<String, String> params = new HashMap<String, String>();
      params.put("inputDir", parseObject.getString("data"));
      params.put("convertType", "1");
      String json = convert(params);
      parseObject = JSON.parseObject(json);
      JSONArray jsonArray = parseObject.getJSONArray("data");
      String url = jsonArray.getString(0);
      url = url.replace(yzOfficeAddr, "");
      yzPreview = new YzPreview();
      yzPreview.setMd5(testUpload.getMd5());
      yzPreview.setBrowseCount(0);
      yzPreview.setDownloadCount(0);
      yzPreview.setPreviewUri(url);
      ypr.save(yzPreview);
    }
    return yzPreview;
  }
}
